{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "574a0a0d",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# Arrays\n",
    "\n",
    "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/brainpy/blob/master/docs_version2/tutorial_math/array.ipynb)\n",
    "[![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/brainpy/brainpy/blob/master/docs_version2/tutorial_math/array.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcca0b77",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "@[Chaoming Wang](https://github.com/chaoming0625)\n",
    "@[Xiaoyu Chen](mailto:c-xy17@tsinghua.org.cn)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ad12762",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "```{note}\n",
    "If you have the basic knowledge about [NumPy](https://numpy.org/) (the ``array`` here is the same as the ``ndarray`` in NumPy), you can skip this section.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe675f5c",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "In this section, we are going to understand:\n",
    "\n",
    "- What is a ``array``?\n",
    "- How to create a ``array``?\n",
    "- What operations are supported for a ``array``?"
   ]
  },
  {
   "cell_type": "code",
   "id": "16447f92",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.684874Z",
     "start_time": "2025-10-06T03:59:34.862531Z"
    }
   },
   "source": [
    "import brainpy.math as bm\n",
    "\n",
    "bm.set_platform('cpu')"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "cell_type": "markdown",
   "id": "187c7b32",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## What is ``array``?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7265c460",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "A array is a homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of non-negative integers. The dimensions of an array are called **axes**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bafe6dea",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "In the following picture, the 1D array (`[7, 2, 9, 10]`) only has one axis. There are 4 elements in this axis, so the shape of the array is `(4,)`. \n",
    "\n",
    "By contrast, the 2D array\n",
    "\n",
    "```python\n",
    "[[5.2, 3.0, 4.5], \n",
    " [9.1, 0.1, 0.3]]\n",
    "```\n",
    "has 2 axes. The first axis has a length of 2 and the second has a length of 3. Therefore, the shape of the 2D array is `(2, 3)`. \n",
    "\n",
    "Similarly, the 3D array has 3 axes, with the dimensions `(4, 3, 2)` in each axis, respectively. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd84ca26",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "<center><img src=\"../_static/numpy_arrays.png\" width=\"600 px\"></center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2602fe69",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "A array has several important attributes:\n",
    "\n",
    "- **.ndim**: the number of axes (dimensions) of the array.\n",
    "\n",
    "- **.shape**: the dimensions of the array. This is a tuple of integers indicating the size of the array in each dimension. For a matrix with n rows and m columns, the shape will be `(n,m)`. The length of the shape tuple is therefore the number of axes, `ndim`.\n",
    "\n",
    "- **.size**: the total number of elements of the array. This is equal to the product of the elements of shape.\n",
    "\n",
    "- **.dtype**: an object describing the type of the elements in the array. One can create or specify dtypes using standard Python types."
   ]
  },
  {
   "cell_type": "code",
   "id": "804ef92d",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.725067Z",
     "start_time": "2025-10-06T03:59:38.692255Z"
    }
   },
   "source": [
    "a = bm.arange(15).reshape((3, 5))\n",
    "\n",
    "a"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([[ 0,  1,  2,  3,  4],\n",
       "       [ 5,  6,  7,  8,  9],\n",
       "       [10, 11, 12, 13, 14]], dtype=int32)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "id": "97002def",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.760312Z",
     "start_time": "2025-10-06T03:59:38.756513Z"
    }
   },
   "source": [
    "a.shape"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 5)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "id": "3c2abbb8",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.798749Z",
     "start_time": "2025-10-06T03:59:38.791126Z"
    }
   },
   "source": [
    "a.ndim"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "id": "84bd85a2",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.826016Z",
     "start_time": "2025-10-06T03:59:38.821664Z"
    }
   },
   "source": [
    "a.dtype"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dtype('int32')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "markdown",
   "id": "940e113d",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## How to create a ``array``?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1e35b10",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "There are several ways to create a array."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87d939a2",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 1. ``array()``, ``zeros()`` and ``ones()``"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38b7ea36",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "The basic method is to convert Python sequences into arrays by ``bm.array()``. For example："
   ]
  },
  {
   "cell_type": "code",
   "id": "a02f438b",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.860873Z",
     "start_time": "2025-10-06T03:59:38.845607Z"
    }
   },
   "source": [
    "bm.array([2, 3, 4])"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([2, 3, 4]), dtype=int32)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "id": "7ccf8dba",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.882279Z",
     "start_time": "2025-10-06T03:59:38.867880Z"
    }
   },
   "source": [
    "bm.array([(1.5, 2, 3), (4, 5, 6)])"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([[1.5, 2. , 3. ],\n",
       "                   [4. , 5. , 6. ]]),\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "cell_type": "markdown",
   "id": "83124b46",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Often, the elements of an array are originally unknown, but its size is known. Therefore, you can use placeholder functions to create arrays, like:"
   ]
  },
  {
   "cell_type": "code",
   "id": "e302c3c5",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.965960Z",
     "start_time": "2025-10-06T03:59:38.930957Z"
    }
   },
   "source": [
    "# \"bm.zeros()\" creates an array full of zeros\n",
    "\n",
    "bm.zeros((3, 4))"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([[0., 0., 0., 0.],\n",
       "                   [0., 0., 0., 0.],\n",
       "                   [0., 0., 0., 0.]]),\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "id": "bc5e01f2",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:38.992831Z",
     "start_time": "2025-10-06T03:59:38.988173Z"
    }
   },
   "source": [
    "# \"bm.ones()\" creates an array full of ones\n",
    "\n",
    "bm.ones((3, 4))"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([[1., 1., 1., 1.],\n",
       "                   [1., 1., 1., 1.],\n",
       "                   [1., 1., 1., 1.]]),\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "markdown",
   "id": "56f9983a",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 2. ``linspace()`` and ``arange()``"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e57773a",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Another two commonly used 1D array creation functions are ``bm.linspace()`` and ``bm.arange()``. \n",
    "\n",
    "``bm.arange()`` creates arrays with regularly incrementing values. It receives \"start\", \"end\", and \"step\" settings. "
   ]
  },
  {
   "cell_type": "code",
   "id": "c075e4bb",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.037414Z",
     "start_time": "2025-10-06T03:59:39.018306Z"
    }
   },
   "source": [
    "# if only one argument \"A\" are provided, the function will  \n",
    "# recognize the \"start = 0\", \"end = A\", and \"step = 1\" .\n",
    "\n",
    "bm.arange(10)  "
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), dtype=int32)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "id": "ea561d1b",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.059205Z",
     "start_time": "2025-10-06T03:59:39.044579Z"
    }
   },
   "source": [
    "# if two argument \"A, B\" are provided, the function will  \n",
    "# recognize the \"start = A\", \"end = B\", and \"step = 1\" .\n",
    "\n",
    "bm.arange(2, 10, dtype=float)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([2., 3., 4., 5., 6., 7., 8., 9.]), dtype=float32)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "id": "7d06eec5",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.080926Z",
     "start_time": "2025-10-06T03:59:39.066649Z"
    }
   },
   "source": [
    "# if three argument \"A, B, C\" are provided, the function will  \n",
    "# recognize the \"start = A\", \"end = B\", and \"step = C\" .\n",
    "\n",
    "bm.arange(2, 3, 0.1)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([2.       , 2.1      , 2.1999998, 2.2999997, 2.3999996, 2.4999995,\n",
       "                   2.5999994, 2.6999993, 2.7999992, 2.8999991]),\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 12
  },
  {
   "cell_type": "markdown",
   "id": "675737c1",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Due to the finite floating-point precision, it is generally impossible to predict the number of elements obtained by ``bm.arange()``. For this reason, it is usually better to use the function ``bm.linspace()`` that receives  \"start\", \"end\", and \"num\" settings."
   ]
  },
  {
   "cell_type": "code",
   "id": "279b7a7b",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.134482Z",
     "start_time": "2025-10-06T03:59:39.093447Z"
    }
   },
   "source": [
    "bm.linspace(2, 3, 10)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([2.       , 2.1111112, 2.2222223, 2.3333333, 2.4444447, 2.5555556,\n",
       "                   2.6666667, 2.777778 , 2.8888888, 3.       ]),\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 13
  },
  {
   "cell_type": "markdown",
   "id": "5acb15fa",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 3. Random sampling"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3ca4b8a",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "``brainpy.math`` module provides convenient [random sampling functions](../apis/math/comparison.html#random-sampling). This module contains some simple random data generation methods, some permutation and distribution functions, and random generator functions. Here I just give several examples. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cecff12d",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``brainpy.math.random.rand(d0, d1, ..., dn)``\n",
    "\n",
    "This function of random module is used to generate random numbers or values in a given shape."
   ]
  },
  {
   "cell_type": "code",
   "id": "d557af23",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.348723Z",
     "start_time": "2025-10-06T03:59:39.157761Z"
    }
   },
   "source": [
    "bm.random.rand(5, 2)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([[0.65127814, 0.11476481],\n",
       "       [0.50711405, 0.7373568 ],\n",
       "       [0.41114306, 0.05597174],\n",
       "       [0.6870688 , 0.16315603],\n",
       "       [0.94323957, 0.4851582 ]], dtype=float32)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 14
  },
  {
   "cell_type": "markdown",
   "id": "1c0fbd01",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``brainpy.math.random.randn(d0, d1, ..., dn)``\n",
    "\n",
    "This function of random module returns a sample from the \"standard normal\" distribution."
   ]
  },
  {
   "cell_type": "code",
   "id": "7ea58428",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.493325Z",
     "start_time": "2025-10-06T03:59:39.374034Z"
    }
   },
   "source": [
    "bm.random.randn(5, 2)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([[ 0.26297134,  0.9452616 ],\n",
       "       [-0.33228904, -1.8911517 ],\n",
       "       [-0.2829688 , -0.08837413],\n",
       "       [-0.98996675, -0.20445131],\n",
       "       [ 1.9176025 , -0.19175233]], dtype=float32)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "markdown",
   "id": "54633332",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``brainpy.math.random.randint(low, high[, size, dtype])``\n",
    "\n",
    "This function of random module is used to generate random integers from inclusive(low) to exclusive(high)."
   ]
  },
  {
   "cell_type": "code",
   "id": "76fa88e8",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.633428Z",
     "start_time": "2025-10-06T03:59:39.499020Z"
    }
   },
   "source": [
    "bm.random.randint(0, 3, size=10)  "
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([0, 0, 1, 1, 0, 0, 0, 2, 0, 1], dtype=int32)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 16
  },
  {
   "cell_type": "markdown",
   "id": "06cc77aa",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``brainpy.math.random.random([size])``\n",
    "\n",
    "This function of random module is used to generate random floats number in the half-open interval [0.0, 1.0)."
   ]
  },
  {
   "cell_type": "code",
   "id": "c9019259",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:39.924834Z",
     "start_time": "2025-10-06T03:59:39.642785Z"
    }
   },
   "source": [
    "bm.random.random((3, 2))"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([[0.1710056 , 0.828014  ],\n",
       "       [0.5423089 , 0.93946946],\n",
       "       [0.3141142 , 0.49604154]], dtype=float32)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "cell_type": "markdown",
   "id": "938535b8",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "``brainpy.math`` module also provides permutation functions."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6ee55f1",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``brainpy.math.random.shuffle()``\n",
    "\n",
    "This function is used to modify a sequence in-place by shuffling its contents."
   ]
  },
  {
   "cell_type": "code",
   "id": "a8757e3c",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.063363Z",
     "start_time": "2025-10-06T03:59:39.947783Z"
    }
   },
   "source": [
    "bm.random.shuffle( bm.arange(10) )  "
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([5, 0, 7, 6, 4, 1, 3, 8, 9, 2], dtype=int32)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "cell_type": "markdown",
   "id": "bc996146",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``brainpy.math.random.permutation()``\n",
    "\n",
    "This function permute a sequence randomly or return a permuted range."
   ]
  },
  {
   "cell_type": "code",
   "id": "3a99ec7e",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.077234Z",
     "start_time": "2025-10-06T03:59:40.070912Z"
    }
   },
   "source": [
    "bm.random.permutation( bm.arange(10) )  "
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([7, 9, 6, 8, 4, 1, 3, 0, 2, 5], dtype=int32)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 19
  },
  {
   "cell_type": "markdown",
   "id": "30aeb977",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "``brainpy.math`` module also provides functions to sample distributions."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52d00e4d",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``beta(a, b[, size])``\n",
    "\n",
    "This function is used to draw samples from a Beta distribution."
   ]
  },
  {
   "cell_type": "code",
   "id": "5c5964ff",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.581160Z",
     "start_time": "2025-10-06T03:59:40.092071Z"
    }
   },
   "source": [
    "bm.random.beta(2, 3, 10) "
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([0.62699956, 0.8052541 , 0.5896076 , 0.5925579 , 0.2377615 ,\n",
       "       0.38714758, 0.63314587, 0.32709256, 0.6149483 , 0.1855493 ],      dtype=float32)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 20
  },
  {
   "cell_type": "markdown",
   "id": "a14b6cf0",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "- ``exponential([scale, size])``\n",
    "\n",
    "This function is used to draw sample from an exponential distribution."
   ]
  },
  {
   "cell_type": "code",
   "id": "366da47d",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.744851Z",
     "start_time": "2025-10-06T03:59:40.623365Z"
    }
   },
   "source": [
    "bm.random.exponential(1, 10) "
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([0.8758875 , 0.79082644, 0.71387357, 0.19460419, 1.4066066 ,\n",
       "       1.6612668 , 0.48084384, 2.7353883 , 0.2542463 , 0.23643894],      dtype=float32)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 21
  },
  {
   "cell_type": "markdown",
   "id": "7ecdde7e",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "More sampling methods please see [random sampling functions](../apis/math/comparison.html#random-sampling)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2df84d15",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 4. Other methods"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f5798cc",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Moreover, there are many other methods we can use to create arrays, including:\n",
    "\n",
    "- Conversion from other Python structures (i.e. lists and tuples)\n",
    "- Intrinsic NumPy array creation functions (e.g. ``arange``, ``ones``, ``zeros``, etc.)\n",
    "- Use of special library functions (e.g., ``random``)\n",
    "- Replicating, joining, or mutating existing arrays\n",
    "- Reading arrays from disk, either from standard or custom formats\n",
    "- Creating arrays from raw bytes through the use of strings or buffers\n",
    "\n",
    "For details of these methods, please see [NumPy tutorial: Array creation](https://numpy.org/doc/stable/user/basics.creation.html). Most of these methods are supported in BrainPy. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef4faa23",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Supported operations on ``array``"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ece918ae",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "All the operations in BrainPy are based on arrays. Therefore it is necessary to know what operations supported in each array object."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f35d70ab",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Basic operations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4dfd8676",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Arithmetic operators on arrays apply element-wise. Let's take \"+\", \"-\", \"\\*\", and \"/\" as examples."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b04e77e",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "We first create two arrays:"
   ]
  },
  {
   "cell_type": "code",
   "id": "30d92226",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.800169Z",
     "start_time": "2025-10-06T03:59:40.786148Z"
    }
   },
   "source": [
    "data = bm.array([1, 2])\n",
    "\n",
    "data"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([1, 2]), dtype=int32)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 22
  },
  {
   "cell_type": "code",
   "id": "3d1fca01",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.874451Z",
     "start_time": "2025-10-06T03:59:40.854024Z"
    }
   },
   "source": [
    "ones = bm.ones(2)\n",
    "\n",
    "ones"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(value=Array([1., 1.]), dtype=float32)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 23
  },
  {
   "cell_type": "markdown",
   "id": "f936b802",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/array_dataones.png)"
   ]
  },
  {
   "cell_type": "code",
   "id": "499eabcb",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.917999Z",
     "start_time": "2025-10-06T03:59:40.892385Z"
    }
   },
   "source": [
    "data + ones"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([2., 3.], dtype=float32)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 24
  },
  {
   "cell_type": "markdown",
   "id": "a74d55e5",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/array_plus_ones.png)"
   ]
  },
  {
   "cell_type": "code",
   "id": "9e06b55f",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:40.990673Z",
     "start_time": "2025-10-06T03:59:40.955557Z"
    }
   },
   "source": [
    "data - ones"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([0., 1.], dtype=float32)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 25
  },
  {
   "cell_type": "code",
   "id": "2e12256a",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.048631Z",
     "start_time": "2025-10-06T03:59:41.028859Z"
    }
   },
   "source": [
    "data * data"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([1, 4], dtype=int32)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 26
  },
  {
   "cell_type": "code",
   "id": "ae0285de",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.081793Z",
     "start_time": "2025-10-06T03:59:41.055638Z"
    }
   },
   "source": [
    "data / data"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([1., 1.], dtype=float32)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 27
  },
  {
   "cell_type": "markdown",
   "id": "7af1df5b",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/array_sub_mult_divide.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5547b61",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Aggregation functions can also be performed on arrays, like:\n",
    "\n",
    "- ``.min()``: to get the minimum element;\n",
    "- ``.max()``: to get the maximum element;\n",
    "- ``.sum()``: to get the summation;\n",
    "- ``.mean()``: to get the average;\n",
    "- ``.prod()``: to get the result of multiplying the elements together;\n",
    "- ``.std()``: to get the standard deviation."
   ]
  },
  {
   "cell_type": "code",
   "id": "e1b99345",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.124145Z",
     "start_time": "2025-10-06T03:59:41.101774Z"
    }
   },
   "source": [
    "data = bm.array([1, 2, 3])\n",
    "\n",
    "data.max()"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(3, dtype=int32)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 28
  },
  {
   "cell_type": "code",
   "id": "127265bd",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.173265Z",
     "start_time": "2025-10-06T03:59:41.146432Z"
    }
   },
   "source": [
    "data.min()"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(1, dtype=int32)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 29
  },
  {
   "cell_type": "code",
   "id": "a5ef1939",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.294514Z",
     "start_time": "2025-10-06T03:59:41.261146Z"
    }
   },
   "source": [
    "data.sum()"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(6, dtype=int32)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 30
  },
  {
   "cell_type": "markdown",
   "id": "65c310f2",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/arraye_aggregation.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b40819ee",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "It's very common to specify the aggregation along a row or column. For example, you can find the maximum value within each column by specifying ``axis=0``."
   ]
  },
  {
   "cell_type": "code",
   "id": "c8376c75",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.352791Z",
     "start_time": "2025-10-06T03:59:41.337976Z"
    }
   },
   "source": [
    "a = bm.array([[1, 2],\n",
    "              [5, 3],\n",
    "              [4, 6]])"
   ],
   "outputs": [],
   "execution_count": 31
  },
  {
   "cell_type": "code",
   "id": "6da06a6e",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.396837Z",
     "start_time": "2025-10-06T03:59:41.370588Z"
    }
   },
   "source": [
    "a.max(axis=0)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([5, 6], dtype=int32)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 32
  },
  {
   "cell_type": "code",
   "id": "bc71fbff",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.467300Z",
     "start_time": "2025-10-06T03:59:41.440684Z"
    }
   },
   "source": [
    "a.max(axis=1)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([2, 5, 6], dtype=int32)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 33
  },
  {
   "cell_type": "markdown",
   "id": "633d4879",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/array_matrix_aggregation_row.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab5940d2",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Broadcasting"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86dcb44b",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "array operations are usually done on pairs of arrays on an element-by-element basis. In the simplest case, the two arrays must have exactly the same shape, as in the following example:"
   ]
  },
  {
   "cell_type": "code",
   "id": "fd2104e9",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.521109Z",
     "start_time": "2025-10-06T03:59:41.486355Z"
    }
   },
   "source": [
    "a = bm.array([1.0, 2.0, 3.0])\n",
    "b = bm.array([2.0, 2.0, 2.0])\n",
    "\n",
    "a * b"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([2., 4., 6.], dtype=float32)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 34
  },
  {
   "cell_type": "markdown",
   "id": "7a0d32d7",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "However, the **broadcasting** rule may be relaxed when the shapes of the arrays meet certain constraints. The simplest broadcasting example occurs when a array and a scalar value are combined in an operation:"
   ]
  },
  {
   "cell_type": "code",
   "id": "53fc2b57",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.597231Z",
     "start_time": "2025-10-06T03:59:41.561360Z"
    }
   },
   "source": [
    "a = bm.array([1, 2])\n",
    "b = 1.6\n",
    "\n",
    "a * b"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([1.6, 3.2], dtype=float32, weak_type=True)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 35
  },
  {
   "cell_type": "markdown",
   "id": "226740eb",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/multiply_broadcasting.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc269323",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Similarly, broadcasting can be applied to matrices:"
   ]
  },
  {
   "cell_type": "code",
   "id": "55db2043",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.648940Z",
     "start_time": "2025-10-06T03:59:41.605666Z"
    }
   },
   "source": [
    "data = bm.array([[1, 2],\n",
    "                 [3, 4],\n",
    "                 [5, 6]])\n",
    "\n",
    "ones_row = bm.array([[1, 1]])\n",
    "\n",
    "data + ones_row"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([[2, 3],\n",
       "       [4, 5],\n",
       "       [6, 7]], dtype=int32)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 36
  },
  {
   "cell_type": "markdown",
   "id": "b023e5df",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "![](../_static/matrix_broadcasting.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5cdc9b38",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Under certain constraints, the smaller array can be \"broadcast\" across the larger array so that they have compatible shapes. Broadcasting provides a means of vectorizing array operations so that looping occurs in C instead of Python. It does this without making needless copies of data and usually leads to efficient algorithm implementations."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1b1ce8f",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Generally, the dimensions of two arrays are compatible when\n",
    "\n",
    "- they are equal,\n",
    "\n",
    "- one of them is 1, or\n",
    "\n",
    "- one of them has fewer dimensions\n",
    "\n",
    "If these conditions are not met, an error will occur. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f569ac79",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "For example, according to the broadcasting rules, the following two shapes are compatible:\n",
    "\n",
    "```bash\n",
    "Image  (3d array): 256 x 256 x 3\n",
    "Scale  (1d array):             3\n",
    "Result (3d array): 256 x 256 x 3\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "id": "d736f3ca",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:41.973764Z",
     "start_time": "2025-10-06T03:59:41.666473Z"
    }
   },
   "source": [
    "image = bm.random.random((256, 256, 3))\n",
    "scale = bm.random.random(3)\n",
    "\n",
    "_ = image + scale \n",
    "_ = image - scale \n",
    "_ = image * scale \n",
    "_ = image / scale "
   ],
   "outputs": [],
   "execution_count": 37
  },
  {
   "cell_type": "markdown",
   "id": "2f913a8b",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "These shapes are also compatible:\n",
    "\n",
    "```bash\n",
    "A      (4d array):  8 x 1 x 6 x 1\n",
    "B      (3d array):      7 x 1 x 5\n",
    "Result (4d array):  8 x 7 x 6 x 5\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "id": "e963bb88",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:42.319938Z",
     "start_time": "2025-10-06T03:59:41.984015Z"
    }
   },
   "source": [
    "A = bm.random.random((8, 1, 6, 1))\n",
    "B = bm.random.random((7, 1, 5))\n",
    "\n",
    "_ = A + B \n",
    "_ = A - B \n",
    "_ = A * B \n",
    "_ = A / B "
   ],
   "outputs": [],
   "execution_count": 38
  },
  {
   "cell_type": "markdown",
   "id": "baca833b",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "However, in these examples, the shapes cannot be broadcast:\n",
    "\n",
    "```bash\n",
    "A      (1d array):  3\n",
    "B      (1d array):  4 # trailing dimensions do not match\n",
    "\n",
    "A      (2d array):      2 x 1\n",
    "B      (3d array):  8 x 4 x 3 # second from last dimensions mismatched\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "id": "5708b7e2",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:42.448699Z",
     "start_time": "2025-10-06T03:59:42.327688Z"
    }
   },
   "source": [
    "A = bm.random.random((3,))\n",
    "B = bm.random.random((4,))\n",
    "\n",
    "try:\n",
    "    _ = A + B\n",
    "except Exception as e:\n",
    "    print(e)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "add got incompatible shapes for broadcasting: (3,), (4,).\n"
     ]
    }
   ],
   "execution_count": 39
  },
  {
   "cell_type": "code",
   "id": "d81990ba",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:42.715360Z",
     "start_time": "2025-10-06T03:59:42.484715Z"
    }
   },
   "source": [
    "A = bm.random.random((2, 1))\n",
    "B = bm.random.random((8, 4, 3))\n",
    "\n",
    "try:\n",
    "    _ = A + B\n",
    "except Exception as e:\n",
    "    print(e)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Incompatible shapes for broadcasting: shapes=[(2, 1), (8, 4, 3)]\n"
     ]
    }
   ],
   "execution_count": 40
  },
  {
   "cell_type": "markdown",
   "id": "01e0903c",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "For more details about broadcasting, please see [NumPy documentation: broadcasting](https://numpy.org/doc/stable/user/basics.broadcasting.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f101b22c",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Indexing, Slicing and Iterating"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "998910bf",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "arrays can be indexed, sliced, and iterated over, much like lists and other Python sequences. For examples:"
   ]
  },
  {
   "cell_type": "code",
   "id": "ab88aff5",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:42.765032Z",
     "start_time": "2025-10-06T03:59:42.737666Z"
    }
   },
   "source": [
    "a = bm.arange(10) ** 3\n",
    "\n",
    "a"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729], dtype=int32)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 41
  },
  {
   "cell_type": "code",
   "id": "3a4f3b88",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:42.806835Z",
     "start_time": "2025-10-06T03:59:42.776570Z"
    }
   },
   "source": [
    "a[2]"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(8, dtype=int32)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 42
  },
  {
   "cell_type": "code",
   "id": "25fb491e",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:42.842595Z",
     "start_time": "2025-10-06T03:59:42.819918Z"
    }
   },
   "source": [
    "a[2:5]"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([ 8, 27, 64], dtype=int32)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 43
  },
  {
   "cell_type": "code",
   "id": "167cf529",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-10-06T03:59:43.761769Z",
     "start_time": "2025-10-06T03:59:42.849339Z"
    }
   },
   "source": [
    "# from start to position 6, exclusive, set every 2nd element to 1000,\n",
    "# equivalent to a[0:6:2] = 1000\n",
    "\n",
    "a[:6:2] = 1000\n",
    "\n",
    "a"
   ],
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "JAX arrays are immutable and do not support in-place item assignment. Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method: https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html",
     "output_type": "error",
     "traceback": [
      "\u001B[31m---------------------------------------------------------------------------\u001B[39m",
      "\u001B[31mTypeError\u001B[39m                                 Traceback (most recent call last)",
      "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[44]\u001B[39m\u001B[32m, line 4\u001B[39m\n\u001B[32m      1\u001B[39m \u001B[38;5;66;03m# from start to position 6, exclusive, set every 2nd element to 1000,\u001B[39;00m\n\u001B[32m      2\u001B[39m \u001B[38;5;66;03m# equivalent to a[0:6:2] = 1000\u001B[39;00m\n\u001B[32m----> \u001B[39m\u001B[32m4\u001B[39m a[:\u001B[32m6\u001B[39m:\u001B[32m2\u001B[39m] = \u001B[32m1000\u001B[39m\n\u001B[32m      6\u001B[39m a\n",
      "\u001B[36mFile \u001B[39m\u001B[32m~\\miniconda3\\envs\\bdp\\Lib\\site-packages\\jax\\_src\\numpy\\array_methods.py:598\u001B[39m, in \u001B[36m_unimplemented_setitem\u001B[39m\u001B[34m(self, i, x)\u001B[39m\n\u001B[32m    594\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34m_unimplemented_setitem\u001B[39m(\u001B[38;5;28mself\u001B[39m, i, x):\n\u001B[32m    595\u001B[39m   msg = (\u001B[33m\"\u001B[39m\u001B[33mJAX arrays are immutable and do not support in-place item assignment.\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m    596\u001B[39m          \u001B[33m\"\u001B[39m\u001B[33m Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method:\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m    597\u001B[39m          \u001B[33m\"\u001B[39m\u001B[33m https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html\u001B[39m\u001B[33m\"\u001B[39m)\n\u001B[32m--> \u001B[39m\u001B[32m598\u001B[39m   \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mTypeError\u001B[39;00m(msg.format(\u001B[38;5;28mtype\u001B[39m(\u001B[38;5;28mself\u001B[39m)))\n",
      "\u001B[31mTypeError\u001B[39m: JAX arrays are immutable and do not support in-place item assignment. Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method: https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html"
     ]
    }
   ],
   "execution_count": 44
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "885641f7",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([ 729,  512,  343,  216,  125, 1000,   27, 1000,    1, 1000], dtype=int32)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[::-1]  # reversed a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "0ff1e887",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.000001\n",
      "1.0\n",
      "10.000001\n",
      "3.0\n",
      "10.000001\n",
      "5.0000005\n",
      "6.0000005\n",
      "7.0000005\n",
      "8.000001\n",
      "9.000001\n"
     ]
    }
   ],
   "source": [
    "for i in a:  # iterate a\n",
    "    print(i**(1 / 3.))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "551f7d10",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "For multi-dimensional arrays, these indices should be given in a tuple separated by commas. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "27480c78",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "b = bm.arange(20).reshape((5, 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "d6154f95",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray(11, dtype=int32)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[2, 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "4e415280",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([ 1,  5,  9, 13, 17], dtype=int32)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[0:5, 1]  # each row in the second column of b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "cdd85a48",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([ 1,  5,  9, 13, 17], dtype=int32)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[:, 1]    # equivalent to the previous example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "0114d873",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([[ 4,  5,  6,  7],\n",
       "             [ 8,  9, 10, 11]], dtype=int32)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[1:3, :]  # each column in the second and third row of b"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2689b28",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "When fewer indices are provided than the number of axes, the missing indices are considered complete slices:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "e422eca2",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([16, 17, 18, 19], dtype=int32)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[-1]   # the last row. Equivalent to b[-1, :]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ae44e83",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "You can also write this using dots as ``b[i, ...]``. The dots ``(...)`` represent as many colons as needed to produce a complete indexing tuple.  For example, if x is an array with 5 axes, then\n",
    "\n",
    "- ``x[1, 2, ...]`` is equivalent to ``x[1, 2, :, :, :]``,\n",
    "\n",
    "- ``x[..., 3]`` to ``x[:, :, :, :, 3]`` and\n",
    "\n",
    "- ``x[4, ..., 5, :]`` to ``x[4, :, :, 5, :]``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "47c9cc2c",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "c = bm.arange(48).reshape((6, 4, 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "2999745b",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([[ 8,  9],\n",
       "             [10, 11],\n",
       "             [12, 13],\n",
       "             [14, 15]], dtype=int32)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c[1, ...]  # same as c[1, :, :] or c[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "6e0599df",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray([[ 1,  3,  5,  7],\n",
       "             [ 9, 11, 13, 15],\n",
       "             [17, 19, 21, 23],\n",
       "             [25, 27, 29, 31],\n",
       "             [33, 35, 37, 39],\n",
       "             [41, 43, 45, 47]], dtype=int32)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c[..., 1]  # same as c[:, :, 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5576265",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Iterating over multidimensional arrays is done with respect to the first axis:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "d2ebe164",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3]\n",
      "[4 5 6 7]\n",
      "[ 8  9 10 11]\n",
      "[12 13 14 15]\n",
      "[16 17 18 19]\n"
     ]
    }
   ],
   "source": [
    "for row in b:\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50ea91b6",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "For more methods or advanced indexing and index tricks, please see [NumPy tutorial: Indexing](https://numpy.org/doc/stable/user/basics.indexing.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9eedce6d",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Mathematical functions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5576be3d",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "arrays support many other functions, including\n",
    "\n",
    "- [mathematical functions](https://numpy.org/doc/stable/reference/routines.math.html)\n",
    "- [logical functions](https://numpy.org/doc/stable/reference/routines.logic.html)\n",
    "- [statistics functions](https://numpy.org/doc/stable/reference/routines.statistics.html)\n",
    "- [window functions](https://numpy.org/doc/stable/reference/routines.window.html)\n",
    "- [sorting, searching, and counting functions](https://numpy.org/doc/stable/reference/routines.sort.html)\n",
    "- and others.\n",
    "\n",
    "Most of these functions can be found in ``brainpy.math`` module. Let's take a look at trigonometric, hyperbolic, and rounding functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "2f1c90e6",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "JaxArray(DeviceArray([0.        , 0.11111111, 0.22222222, 0.33333334, 0.44444445,\n",
       "                      0.5555556 , 0.6666667 , 0.7777778 , 0.8888889 , 1.        ],            dtype=float32))"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = bm.linspace(0, 1, 10)\n",
    "\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "056df35d",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "JaxArray(DeviceArray([0.        , 0.11088263, 0.22039774, 0.32719472, 0.42995638,\n",
       "                      0.5274154 , 0.6183698 , 0.7016979 , 0.7763719 , 0.84147096],            dtype=float32))"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# trigonometric functions\n",
    "\n",
    "bm.sin(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "1fef793c",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "JaxArray(DeviceArray([0.        , 0.11134101, 0.2240931 , 0.3398369 , 0.460554  ,\n",
       "                      0.58903104, 0.7297277 , 0.8911225 , 1.0949141 , 1.5707964 ],            dtype=float32))"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bm.arcsin(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "2f3c8c02",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "JaxArray(DeviceArray([0.        , 0.11133985, 0.22405571, 0.33954054, 0.45922154,\n",
       "                      0.58457786, 0.7171585 , 0.8586021 , 1.0106566 , 1.1752012 ],            dtype=float32))"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# hyperbolic functions\n",
    "\n",
    "bm.sinh(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "3084f5bd",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "JaxArray(DeviceArray([0., 0., 0., 0., 0., 1., 1., 1., 1., 1.], dtype=float32))"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# rounding functions\n",
    "\n",
    "bm.round(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "66de6eeb",
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DeviceArray(5., dtype=float32)"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sum function\n",
    "\n",
    "bm.sum(d)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "279.273px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
